import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Client } from "src/modules/client/client.entity";
import { ClientService } from "src/modules/client/client.service";
import { Company } from "src/modules/company/company.entity";
import { CompanyService } from "src/modules/company/company.service";
import { User } from "src/modules/user/user.entity";
import { UserService } from "src/modules/user/user.service";
import { dateNewFirst } from "src/utils/util";
import { Repository } from "typeorm";
import { Delivery } from "./delivery.entity";
import { UpdateDeliveryDto } from "./dto/update-delivery.dto";

@Injectable()
export class DeliveryService {
  constructor(
    @InjectRepository(Delivery)
    private readonly deliveryRepository: Repository<Delivery>,
    private readonly companyService: CompanyService,
    private readonly usersService: UserService,
    private readonly clientService: ClientService
  ) {}
  async findAll(): Promise<[Delivery[], number]> {
    const res = await this.deliveryRepository.findAndCount({
      relations: ["deliveryItems", "client"],
    });
    const deliverys = res[0].sort(dateNewFirst);
    return [deliverys, res[1]];
  }
  async findByCompany(
    company: string | Company
  ): Promise<[Delivery[], number]> {
    if (!(company instanceof Company)) {
      company = await this.companyService.find(company);
    }
    const ans = await this.deliveryRepository.findAndCount({
      where: { company },
      relations: ["deliveryItems", "client"],
    });
    const deliveries = ans[0].sort(dateNewFirst);
    return [deliveries, ans[1]];
  }
  async findByClient(client: string | Client): Promise<[Delivery[], number]> {
    if (!(client instanceof Client)) {
      client = await this.clientService.find(client);
    }
    const ans = await this.deliveryRepository.findAndCount({
      where: { client },
      relations: ["deliveryItems"],
    });
    const deliveries = ans[0].sort(dateNewFirst);
    return [deliveries, ans[1]];
  }
  find(delivery: string | Delivery): Promise<Delivery> {
    const id = delivery instanceof Delivery ? delivery.id : delivery;
    return this.deliveryRepository.findOneOrFail({
      where: { id },
      relations: ["deliveryItems", "client", "user", "company"],
    });
  }
  async findLast(companyId?: string): Promise<Delivery> {
    if (companyId) {
      const company = await this.companyService.find(companyId);
      return this.deliveryRepository.findOne({
        where: { company },
        order: {
          date: "DESC",
        },
      });
    }
    return this.deliveryRepository.findOne({
      order: {
        date: "DESC",
      },
    });
  }
  async count(companyId?: string): Promise<number> {
    if (companyId) {
      const company = await this.companyService.find(companyId);
      return this.deliveryRepository.count({ company });
    }
    return this.deliveryRepository.count();
  }
  /** 更新送货单的基本信息 */
  async update(
    updateDeliveryDto: UpdateDeliveryDto,
    delivery: string | Delivery,
    user: string | User
  ) {
    if (!(delivery instanceof Delivery)) {
      delivery = await this.deliveryRepository.findOneOrFail(delivery);
    }
    if (!(user instanceof User)) {
      user = await this.usersService.find(user);
    }
    Object.assign(delivery, updateDeliveryDto);
    delivery.user = user;
    return this.deliveryRepository.save(delivery);
  }
  findOneWithCompany(id: string): Promise<Delivery> {
    return this.deliveryRepository.findOneOrFail(id, {
      relations: ["company"],
    });
  }
}
